Apache Tapestry একটি শক্তিশালী Java-based framework, যা RESTful API তৈরি এবং ব্যবহারের জন্য উপযুক্ত। যখন আপনি RESTful API তৈরি করেন, তখন Authentication এবং API Versioning খুবই গুরুত্বপূর্ণ বিষয়, বিশেষত যখন আপনি সিকিউরিটি এবং বর্ধিত স্কেলেবল অ্যাপ্লিকেশন তৈরি করতে চান।
এই টিউটোরিয়ালে, আমরা REST Authentication এবং API Versioning কিভাবে Tapestry ফ্রেমওয়ার্কে কার্যকরভাবে ব্যবহার করা যায়, তা দেখব।
RESTful API-তে Authentication ব্যবহারের মাধ্যমে আপনি নিশ্চিত করতে পারেন যে শুধুমাত্র অনুমোদিত ব্যবহারকারীরা আপনার API ব্যবহার করতে পারবেন। Authentication প্রক্রিয়া সম্পাদন করার জন্য প্রধানত দুটি পদ্ধতি ব্যবহৃত হয়:
Basic Authentication তে, ব্যবহারকারী নাম এবং পাসওয়ার্ড সরাসরি HTTP হেডারে পাঠানো হয়। এটি সাধারণত ছোট অ্যাপ্লিকেশনে ব্যবহৃত হয়, তবে উচ্চ নিরাপত্তা ব্যবস্থায় এটি কম ব্যবহৃত হয়।
আপনি Tapestry-তে Basic Authentication প্রয়োগ করার জন্য HTTP request filter তৈরি করতে পারেন।
package com.example.services;
import org.apache.tapestry5.services.Filter;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Response;
import org.apache.tapestry5.services.ServiceOverride;
public class AuthenticationFilter implements Filter {
private final String USERNAME = "admin";
private final String PASSWORD = "password123"; // Secure password should be used
@Override
public void service(Request request, Response response) throws Exception {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !isValid(authHeader)) {
response.setStatus(401); // Unauthorized
response.getOutputStream().write("Unauthorized Access".getBytes());
return;
}
// Proceed to next filter if authorized
response.invokeNext();
}
private boolean isValid(String authHeader) {
// Basic Authentication is Base64 encoded, so you need to decode and validate
String credentials = new String(java.util.Base64.getDecoder().decode(authHeader.split(" ")[1]));
String[] parts = credentials.split(":");
if (parts.length == 2) {
return USERNAME.equals(parts[0]) && PASSWORD.equals(parts[1]);
}
return false;
}
}
web.xml ফাইলে এই ফিল্টারটি রেজিস্টার করুন:
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>com.example.services.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>
এই কনফিগারেশনটি /api/ পাথের জন্য ফিল্টারটি প্রয়োগ করবে, যা Basic Authentication সুরক্ষিত করবে।
Token-based Authentication যেমন JWT (JSON Web Tokens) নিরাপদ এবং স্কেলেবল এক্সেস মেকানিজম সরবরাহ করে। এখানে ব্যবহারকারী লগইন করার পর একটি টোকেন জেনারেট করা হয়, যা পরবর্তী রিকোয়েস্টে ব্যবহারকারীকে চিহ্নিত করতে সাহায্য করে।
package com.example.services;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JWTUtil {
private static final String SECRET_KEY = "secretKey123";
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1 hour expiration
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public static boolean validateToken(String token) {
try {
Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
package com.example.services;
import org.apache.tapestry5.services.Filter;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Response;
public class JWTAuthenticationFilter implements Filter {
@Override
public void service(Request request, Response response) throws Exception {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !JWTUtil.validateToken(authHeader.split(" ")[1])) {
response.setStatus(401); // Unauthorized
response.getOutputStream().write("Unauthorized Access".getBytes());
return;
}
response.invokeNext();
}
}
<filter>
<filter-name>JWTAuthenticationFilter</filter-name>
<filter-class>com.example.services.JWTAuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>JWTAuthenticationFilter</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>
API Versioning একটি গুরুত্বপূর্ণ বিষয় যখন আপনি ওয়েব API তৈরি করেন। এর মাধ্যমে আপনি একাধিক সংস্করণ সরবরাহ করতে পারেন, যা অ্যাপ্লিকেশন বা ফিচার আপডেটের সময় পুরানো API কাস্টমারের জন্য সমর্থিত থাকে।
API Versioning এর তিনটি সাধারণ পদ্ধতি:
/api/v1/resource
X-API-Version: 1
/api/resource?version=1
package com.example.pages;
import org.apache.tapestry5.annotations.Path;
public class ApiV1Resource {
public String getApiVersion() {
return "v1";
}
}
URI Mapping (web.xml):
<servlet-mapping>
<servlet-name>tapestry</servlet-name>
<url-pattern>/api/v1/*</url-pattern>
</servlet-mapping>
এটি v1
সংস্করণে API রিসোর্সগুলো প্রদান করবে।
package com.example.services;
import org.apache.tapestry5.services.Request;
public class VersionedApiService {
public void processRequest(Request request) {
String apiVersion = request.getHeader("X-API-Version");
if ("1".equals(apiVersion)) {
// Handle v1 API version logic
} else if ("2".equals(apiVersion)) {
// Handle v2 API version logic
}
}
}
এই কোডটি API সংস্করণের উপর ভিত্তি করে request হেডার থেকে ভিন্ন সংস্করণ প্রক্রিয়া করে।
REST Authentication এবং API Versioning ওয়েব API সিকিউরিটি এবং স্কেলেবিলিটির জন্য অত্যন্ত গুরুত্বপূর্ণ। Tapestry তে, আপনি Basic Authentication অথবা JWT (Token-based Authentication) ব্যবহার করে API সিকিউর করতে পারেন এবং API Versioning প্রয়োগ করে একাধিক API সংস্করণ পরিচালনা করতে পারেন। URI versioning, header versioning, এবং query parameter versioning এর মাধ্যমে আপনি সহজে সংস্করণ নিয়ন্ত্রণ করতে পারেন।
Read more